package com.spring.framework.config.life;

import com.spring.framework.config.value.ValuePropertiesDefault;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * 这个注解就类似于XML配置中的depends-on属性，用于控制某一个或者多个bean在该bean实例化之前先顺序实例化，在该bean销毁之后倒序销毁。
 * 对于注解标注的bean如果是prototype则DependsOn无效，而对于被依赖的bean即使是prototype的也会顺序初始化，但不会执行销毁回调。
 * <p>
 * 更多详情可以看基于XML配置的depends-on部分。
 *
 * @author xuweizhi
 * @since 2020/12/15 16:07
 */
@Component
public class BeanDependsOn {

	/**
	 * 可以指定多一个依赖的bean多个bean将按照顺序先后初始化
	 * 销毁时按照倒序销毁
	 */
	@DependsOn({"beanDependsOnC", "beanDependsOnB"})
	@Component("beanDependsOnA")
	//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
	public static class BeanDependsOnA {

		@PostConstruct
		public void postConstruct() {
			System.out.println("BeanDependsOnA bean创建回调");
		}

		@PreDestroy
		public void preDestroy() {
			System.out.println("BeanDependsOnA bean销毁回调");
		}

		public BeanDependsOnA() {
			System.out.println("BeanDependsOnA 构造器");
		}

	}

	@Component("beanDependsOnB")
	public static class BeanDependsOnB {

		@PostConstruct
		public void postConstruct() {
			System.out.println("BeanDependsOnB bean创建回调");
		}

		@PreDestroy
		public void preDestroy() {
			System.out.println("BeanDependsOnB bean销毁回调");
		}

		public BeanDependsOnB() {
			System.out.println("BeanDependsOnB 构造器");
		}
	}

	@Component("beanDependsOnC")
	//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
	public static class BeanDependsOnC {

		@PostConstruct
		public void postConstruct() {
			System.out.println("BeanDependsOnC bean创建回调");
		}

		@PreDestroy
		public void preDestroy() {
			System.out.println("BeanDependsOnC bean销毁回调");
		}

		public BeanDependsOnC() {
			System.out.println("BeanDependsOnC 构造器");
		}

	}

	public static void main(String[] args) {
		System.out.println("---创建容器---");
		//新建容器，将会实例化单例的bean，触发bean创建回调
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanDependsOn.class);
		//System.out.println(ac.getBean("beanDependsOnA", BeanDependsOn.BeanDependsOnA.class));
		//关闭容器，将会销毁bean，触发单例bean的销毁回调
		System.out.println("---容器关闭---");
		applicationContext.close();
	}
}
